agora inbox for [email protected]  
help / color / mirror / Atom feed
Re: tracking owner of extension-managed objects
812+ messages / 3 participants
[nested] [flat]

* Re: tracking owner of extension-managed objects
@ 2016-01-01 00:06 Jim Nasby <[email protected]>
  2016-01-01 01:19 ` Re: tracking owner of extension-managed objects Chapman Flack <[email protected]>
  0 siblings, 1 reply; 812+ messages in thread

From: Jim Nasby @ 2016-01-01 00:06 UTC (permalink / raw)
  To: Chapman Flack <[email protected]>; Robert Haas <[email protected]>; +Cc: Tom Lane <[email protected]>; pgsql-hackers

On 12/31/15 3:49 PM, Chapman Flack wrote:
> On 12/23/15 15:02, Jim Nasby wrote:
>> >BTW, I've been pondering a very similar problem to this. I'm working on a
>> >metacoding framework, and it's inevitable that at some point it will want to
>> >know what objects it's created....
>> >
>> >I was planning on just making a best possible attempt and solving this in an
>> >extension via a combination of event triggers, reg* and other voodoo,
> In the voodoo department, I guess PL/Java could accompany each loading of
> a jar 'foo' with a 'CREATE TYPE sqlj.voodoo_foo AS ()' which is about as
> lightweight as it gets, and an extra regtype column in the jar_repository
> table could carry the Oid of that type.

Hmm, interesting idea.

> How well will pg_dump/restore handle that voodoo? I suppose they'll
> reliably recreate the types before loading the table with a regtype
> column, and by typing the column as regtype, the dump will refer to
> the type by name, and therefore work even if pg_dump is not given
> the --oids option?

Yes, assuming the type hasn't been dropped. Otherwise regtype spits out 
the OID that used to be assigned, which AFAICT is completely useless for 
a non-system object.

I've thought about creating a datatype that worked the same as the reg* 
types, but also implemented a "foreign key" back to the relevant catalog 
so things couldn't just vanish on you. (Since you obviously can't do an 
FK to a catalog this would have to be simulated with event triggers).

> On 12/21/15 12:46, Tom Lane wrote:
>> >(I guess there are problems with extensions trying to do such things at
>> >all, since we don't provide a way for extensions to hook into the DROP
>> >mechanisms.  Perhaps that should be fixed.)
>
> Ok, how numerous would be the problems with this:
>
>
> - The classid and refclassid columns (in both pg_shdepend and pg_depend)
>    are currently Oid columns referencing pg_class.oid.  The catalog
>    definition would not preclude putting the oid of a non-system table
>    there.  The*documentation*  says it has to be the oid of a system
>    catalog, and surely there is code that currently would be surprised by
>    an entry that wasn't (for example, default: elog(ERROR, "unrecognized
>    object class..." in getObjectClass).
>    But even now, looking at recordDependencyOn or shdepAddDependency,
>    I don't see that the code would prevent such an entry being added.

Either I'm not understanding what you're saying here, or you're confused 
about those two columns.

Those columns are there to tell you what *kind* of objects are involved 
in the dependency. For example, a function will have two entries. 
classid will be 1255 (pg_proc) for both of them. refclassid will be 2612 
(pg_language) for one and 2615 (pg_namespace) for the other.

Oh, were you thinking of having a new classid that represented files on 
disk?
-- 
Jim Nasby, Data Architect, Blue Treble Consulting, Austin TX
Experts in Analytics, Data Architecture and PostgreSQL
Data in Trouble? Get it in Treble! http://BlueTreble.com


-- 
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers



^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* Re: tracking owner of extension-managed objects
  2016-01-01 00:06 Re: tracking owner of extension-managed objects Jim Nasby <[email protected]>
@ 2016-01-01 01:19 ` Chapman Flack <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Chapman Flack @ 2016-01-01 01:19 UTC (permalink / raw)
  To: Jim Nasby <[email protected]>; Robert Haas <[email protected]>; +Cc: Tom Lane <[email protected]>; pgsql-hackers

On 12/31/15 19:06, Jim Nasby wrote:
> Those columns are there to tell you what *kind* of objects are involved in
> the dependency. For example, a function will have two entries. classid will
> be 1255 (pg_proc) for both of them. refclassid will be 2612 (pg_language)
> for one and 2615 (pg_namespace) for the other.

Right, well, the classid for a function is 1255 because 1255 is the Oid
of a row in pg_class ... and that row happens to describe a relation
named pg_proc, which is the relation in which you find functions.

Now, if you go to that relation, and look for a row whose Oid is the
objid part of the address, that row is the specific function you're
looking for.

So, if I give you the object address (1255, 1397, 0), these are the two
steps you will use to learn what I'm talking about:


SELECT relname FROM pg_class WHERE oid = 1255;
---------
 pg_proc


SELECT * FROM pg_proc WHERE oid = 1397;
-----+-...-+---------+-...
 abs | ... | int4abs | ...



Ok, now what if I give you the object address (17001, 17270, 0) ?
Of course, these oids aren't predefined so they won't be the same
from one database to the next. But in the test database I'm logged
in to right now, you can follow the very same two steps:


SELECT relname FROM pg_class WHERE oid = 17001;
   relname
----------------
 jar_repository


SELECT * FROM jar_repository WHERE oid = 17270;
 jarid | jarname  | jarowner |    jarmanifest    | ...
-------+----------+----------+-------------------+-...
     2 | examples | chap     | Manifest-Versio...| ...


Nothing new has happened here. The algorithm is unchanged.
The object address (17001, 17270, 0) means "the PL/Java examples jar",
in exactly the same way that (1255, 1397, 0) means "the int4abs
function".

(I had to cheat a little and ALTER TABLE jar_repository SET WITH OIDS
because in stock PL/Java it doesn't have them, but that was easy enough.)

The only thing that stops me at present from passing
an ObjectAddress like (17001, 17270, 0) to recordDependencyOn(...)
is that the *documentation* says the classid can't be the Oid
of just *any* old row in pg_class, is has to be the oid of a row
in pg_class *that describes a system catalog*.

As far as the actual code, if I tried that right now I don't actually
think anything would stop me from recording the dependency.
Things would break when I tried to drop something though, because
getObjectClass() would be called on my dependency, not recognize that
Oid among the ones it knows about, and throw an error.

How about having a default case there, saying "hmm, jar_repository,
not a table I recognize, it must belong to some extension. Well, I'll
just go and delete its row with oid = 17270 anyway, and let the extension
that owns it handle the DELETE trigger if any, and we're good to go." ?

To a first approximation, it's as easy as that.  All the rest of my
earlier message was about proposing rules to enforce reasonable
restrictions so the dependency jazz isn't opened up to every old user
table with triggers calling arbitrary code to get all tangled up in
PostgreSQL's DROP internals, but it is opened up in a controlled way
to extensions that create new classes of things to be managed.

-Chap


-- 
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers



^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v1 4/4] Extra tests
@ 2025-08-31 09:10 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-08-31 09:10 UTC (permalink / raw)

Add more tests for trenary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fae..78d1d84ed9a 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- trenary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6fc..19826e50e6d 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	trenary		option_trenary1;
+	trenary		option_trenary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_trenary_reloption(di_relopt_kind, "option_trenary1",
+					   "First trenary option for dummy_index_am",
+					   TRENARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_trenary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_trenary1);
+
+	add_trenary_reloption(di_relopt_kind, "option_trenary2",
+					   "Second trenary option for dummy_index_am",
+					   TRENARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_trenary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TRENARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_trenary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb75..bcf164f5bf7 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_trenary1=true
+ option_trenary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_trenary1=false
+ option_trenary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ERROR:  invalid value for trenary option "option_trenary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ERROR:  invalid value for trenary option "option_trenary1": val4
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ERROR:  invalid value for trenary option "option_trenary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_trenary1=1
+ option_trenary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6a..7e752b12d16 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_trenary1,
+  option_trenary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_trenary1 = false);
+ALTER INDEX dummy_test_idx SET (option_trenary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Trenary
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_trenary1 = 'do_not_know_yet'); -- error. Valid for trenary2 not for trenary1
+ALTER INDEX dummy_test_idx SET (option_trenary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_trenary1);
+ALTER INDEX dummy_test_idx RESET (option_trenary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index e32431ca067..54b3424ef2b 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 051142eed5f..1971d460672 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) trenary options
+-- Tests for trenary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart6784952.tM3a2QDmDi--

--nextPart6187903.UjTJXf6HLC
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi0gCMACgkQPMbfuIHA
Gpi3Dgf/dQxIJ7WM8rL4szT+d+7gCw1BUzA7H4SkLtGM8E+akUvbjt6lFpCKN7fP
dHWTY7NeHsLy8hXB7Z+P4edaHAqNQ7pXtESuC0jBB1Ta5r9f0mUz/tNvyaoj1YPV
SES411gQwABIJ/ZXoqrcAHgmJoyAKZcFWU9HBAhJyL3Da/o7L86wgro4a6ov7cgP
1mJa6WjH1qf1v4PPrZYxLMmU5v3uacNDFowNsQ8+uHs+slUWjkw4VYatdReWla0a
4qBnMaht1Xky3f55YfB7Gx28CBUUPMREUVKFOrcopq95kZ9WASoTJfU9Y80IDPWb
KVcJvYDk5TEL1t48GpFkjZbL9od51w==
=yrfm
-----END PGP SIGNATURE-----

--nextPart6187903.UjTJXf6HLC--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2a 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart4155600.3ZeAukHxDK--

--nextPart4961315.687JKscXgg
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmjGgZ4ACgkQPMbfuIHA
GpgHFgf/dwjUCCKw4wFDpFssAUVnClknwo+DYhgbni6DfBlLM8bjB0CWwZsNGUEv
dGueFJY9q4+3YPon9sqb1KIqBZDtLaGj69U+K+ZtLkjOc8WV4VOmUyZuuSaZh9lw
JFM+d8RZNTemYQ5Nc82YuF+4MDiiM3480vhAr412LMRd/6P4dk+vKDL2kopodhB+
xbZYtARolC/bZaMTla68L/4X5qidfsd4zd+QZjf8JXwv1mq2MZCuHvsuMMViWp3Z
Hf7r4bj407BjEYH/UNpE70iWa65xDCHpRSOYJ6QKFxRnAEYBim6u3G7t85jnHz7O
mVGvRJLeVMgh2l6TCxG7fSJGwh/Qrg==
=Agrf
-----END PGP SIGNATURE-----

--nextPart4961315.687JKscXgg--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread

* [PATCH v2 4/4] Extra tests
@ 2025-09-04 16:28 Nikolay Shaplov <[email protected]>
  0 siblings, 0 replies; 812+ messages in thread

From: Nikolay Shaplov @ 2025-09-04 16:28 UTC (permalink / raw)

Add more tests for ternary reloptions in dummy_index_am module
---
 src/test/modules/dummy_index_am/README        |  1 +
 .../modules/dummy_index_am/dummy_index_am.c   | 36 +++++++++++++-----
 .../dummy_index_am/expected/reloptions.out    | 38 +++++++++++++++++--
 .../modules/dummy_index_am/sql/reloptions.sql | 16 ++++++++
 src/test/regress/expected/reloptions.out      |  4 +-
 src/test/regress/sql/reloptions.sql           |  4 +-
 6 files changed, 81 insertions(+), 18 deletions(-)

diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README
index 61510f02fa..d80aff0db1 100644
--- a/src/test/modules/dummy_index_am/README
+++ b/src/test/modules/dummy_index_am/README
@@ -6,6 +6,7 @@ access method, whose code is kept a maximum simple.
 
 This includes tests for all relation option types:
 - boolean
+- ternary
 - enum
 - integer
 - real
diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c
index 94ef639b6f..bf8446ddc6 100644
--- a/src/test/modules/dummy_index_am/dummy_index_am.c
+++ b/src/test/modules/dummy_index_am/dummy_index_am.c
@@ -22,7 +22,7 @@
 PG_MODULE_MAGIC;
 
 /* parse table for fillRelOptions */
-static relopt_parse_elt di_relopt_tab[6];
+static relopt_parse_elt di_relopt_tab[8];
 
 /* Kind of relation options for dummy index */
 static relopt_kind di_relopt_kind;
@@ -40,6 +40,8 @@ typedef struct DummyIndexOptions
 	int			option_int;
 	double		option_real;
 	bool		option_bool;
+	ternary		option_ternary1;
+	ternary		option_ternary2;
 	DummyAmEnum option_enum;
 	int			option_string_val_offset;
 	int			option_string_null_offset;
@@ -96,23 +98,37 @@ create_reloptions_table(void)
 	di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL;
 	di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool);
 
+	add_ternary_reloption(di_relopt_kind, "option_ternary1",
+					   "First ternary option for dummy_index_am",
+					   TERNARY_UNSET, NULL, AccessExclusiveLock);
+	di_relopt_tab[3].optname = "option_ternary1";
+	di_relopt_tab[3].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_ternary1);
+
+	add_ternary_reloption(di_relopt_kind, "option_ternary2",
+					   "Second ternary option for dummy_index_am",
+					   TERNARY_TRUE, "do_not_know_yet", AccessExclusiveLock);
+	di_relopt_tab[4].optname = "option_ternary2";
+	di_relopt_tab[4].opttype = RELOPT_TYPE_TERNARY;
+	di_relopt_tab[4].offset = offsetof(DummyIndexOptions, option_ternary2);
+
 	add_enum_reloption(di_relopt_kind, "option_enum",
 					   "Enum option for dummy_index_am",
 					   dummyAmEnumValues,
 					   DUMMY_AM_ENUM_ONE,
 					   "Valid values are \"one\" and \"two\".",
 					   AccessExclusiveLock);
-	di_relopt_tab[3].optname = "option_enum";
-	di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM;
-	di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum);
+	di_relopt_tab[5].optname = "option_enum";
+	di_relopt_tab[5].opttype = RELOPT_TYPE_ENUM;
+	di_relopt_tab[5].offset = offsetof(DummyIndexOptions, option_enum);
 
 	add_string_reloption(di_relopt_kind, "option_string_val",
 						 "String option for dummy_index_am with non-NULL default",
 						 "DefaultValue", &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[4].optname = "option_string_val";
-	di_relopt_tab[4].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[4].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[6].optname = "option_string_val";
+	di_relopt_tab[6].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[6].offset = offsetof(DummyIndexOptions,
 									   option_string_val_offset);
 
 	/*
@@ -123,9 +139,9 @@ create_reloptions_table(void)
 						 NULL,	/* description */
 						 NULL, &validate_string_option,
 						 AccessExclusiveLock);
-	di_relopt_tab[5].optname = "option_string_null";
-	di_relopt_tab[5].opttype = RELOPT_TYPE_STRING;
-	di_relopt_tab[5].offset = offsetof(DummyIndexOptions,
+	di_relopt_tab[7].optname = "option_string_null";
+	di_relopt_tab[7].opttype = RELOPT_TYPE_STRING;
+	di_relopt_tab[7].offset = offsetof(DummyIndexOptions,
 									   option_string_null_offset);
 }
 
diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out
index c873a80bb7..ad1b2ea639 100644
--- a/src/test/modules/dummy_index_am/expected/reloptions.out
+++ b/src/test/modules/dummy_index_am/expected/reloptions.out
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -31,16 +33,20 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
          unnest         
 ------------------------
  option_bool=false
+ option_ternary1=true
+ option_ternary2=off
  option_int=5
  option_real=3.1
  option_enum=two
  option_string_val=null
  option_string_null=val
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -49,19 +55,23 @@ ALTER INDEX dummy_test_idx SET (option_enum = 'three');
 ERROR:  invalid value for enum option "option_enum": three
 DETAIL:  Valid values are "one" and "two".
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
-         unnest          
--------------------------
+             unnest              
+---------------------------------
  option_int=10
  option_bool=true
+ option_ternary1=false
+ option_ternary2=do_not_know_yet
  option_real=3.2
  option_string_val=val2
  option_string_null=null
  option_enum=one
-(6 rows)
+(8 rows)
 
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -100,6 +110,26 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 (1 row)
 
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ERROR:  invalid value for ternary option "option_ternary1": 3.4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ERROR:  invalid value for ternary option "option_ternary1": val4
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ERROR:  invalid value for ternary option "option_ternary1": do_not_know_yet
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+             unnest              
+---------------------------------
+ option_ternary1=1
+ option_ternary2=do_not_know_yet
+(2 rows)
+
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql
index 6749d763e6..123540905a 100644
--- a/src/test/modules/dummy_index_am/sql/reloptions.sql
+++ b/src/test/modules/dummy_index_am/sql/reloptions.sql
@@ -18,6 +18,8 @@ SET client_min_messages TO 'notice';
 CREATE INDEX dummy_test_idx ON dummy_test_tab
   USING dummy_index_am (i) WITH (
   option_bool = false,
+  option_ternary1,
+  option_ternary2 = off,
   option_int = 5,
   option_real = 3.1,
   option_enum = 'two',
@@ -30,6 +32,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. SET
 ALTER INDEX dummy_test_idx SET (option_int = 10);
 ALTER INDEX dummy_test_idx SET (option_bool = true);
+ALTER INDEX dummy_test_idx SET (option_ternary1 = false);
+ALTER INDEX dummy_test_idx SET (option_ternary2 = Do_Not_Know_YET);
 ALTER INDEX dummy_test_idx SET (option_real = 3.2);
 ALTER INDEX dummy_test_idx SET (option_string_val = 'val2');
 ALTER INDEX dummy_test_idx SET (option_string_null = NULL);
@@ -40,6 +44,8 @@ SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 -- ALTER INDEX .. RESET
 ALTER INDEX dummy_test_idx RESET (option_int);
 ALTER INDEX dummy_test_idx RESET (option_bool);
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 ALTER INDEX dummy_test_idx RESET (option_real);
 ALTER INDEX dummy_test_idx RESET (option_enum);
 ALTER INDEX dummy_test_idx RESET (option_string_val);
@@ -60,6 +66,16 @@ ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error
 ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error
 SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
 ALTER INDEX dummy_test_idx RESET (option_bool);
+-- Ternary
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 1); -- ok, as true
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 3.4); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'val4'); -- error
+ALTER INDEX dummy_test_idx SET (option_ternary1 = 'do_not_know_yet'); -- error. Valid for ternary2 not for ternary1
+ALTER INDEX dummy_test_idx SET (option_ternary2 = 'do_not_know_yet'); -- ok
+SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx';
+ALTER INDEX dummy_test_idx RESET (option_ternary1);
+ALTER INDEX dummy_test_idx RESET (option_ternary2);
 -- Float
 ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok
 ALTER INDEX dummy_test_idx SET (option_real = true); -- error
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index 1c99f79ab0..6e65cd5c3d 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -98,7 +98,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {fillfactor=13,autovacuum_enabled=false}
 (1 row)
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate);
@@ -116,7 +116,7 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
  {vacuum_truncate=fals}
 (1 row)
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index f5980dafcb..c99673db9e 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -59,7 +59,7 @@ UPDATE pg_class
 ALTER TABLE reloptions_test RESET (illegal_option);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- Tests for future (FIXME) ternary options
+-- Tests for ternary options
 
 -- behave as boolean option: accept unassigned name and truncated value
 DROP TABLE reloptions_test;
@@ -70,7 +70,7 @@ DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_truncate=FaLS);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
 
--- preferred "true" alias is used when storing
+-- preferred "true" alias is stored in pg_class
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test(i INT) WITH (vacuum_index_cleanup=on);
 SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-- 
2.39.2


--nextPart5129932.5fSG56mABF--

--nextPart7913091.MhkbZ0Pkbq
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.
Content-Transfer-Encoding: 7Bit

-----BEGIN PGP SIGNATURE-----

iQEzBAABCgAdFiEE+sk3ebqQKlezKOi8PMbfuIHAGpgFAmi5xzQACgkQPMbfuIHA
GpgVIAf/XPjp6PMbvLKQNz7lPTc3R8PRBXQG4MIj5C5xa3fM5s5uIq/aMYD6CL2g
PycNUWsA/HumkH6h64TYT2JL3oeo2cXO9BU66Dm/wDJqz95eR6KANzfS2UC0qpyf
Qab+JdontqQITiXrvHX4IB9RZRndkJa+OKWHxvzY2oToizXkbPwEDFcQR3+kUPAu
BEl6f6BmJzd9tJAJz5wXINV3TTRe++dmtHkNesmq8c8P4R62PhBkjjGynczCjnke
z319jJS71lEjNsKVvCkzkjpVNTGO7w33rIJQGscW+PUNGhUVB4qDqxfHPGSZS1Sb
fU0Sv+UciXMopbvtezVtK30GBezX8Q==
=RxGQ
-----END PGP SIGNATURE-----

--nextPart7913091.MhkbZ0Pkbq--








^ permalink  raw  reply  [nested|flat] 812+ messages in thread


end of thread, other threads:[~2025-09-04 16:28 UTC | newest]

Thread overview: 812+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2016-01-01 00:06 Re: tracking owner of extension-managed objects Jim Nasby <[email protected]>
2016-01-01 01:19 ` Chapman Flack <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-08-31 09:10 [PATCH v1 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2a 4/4] Extra tests Nikolay Shaplov <[email protected]>
2025-09-04 16:28 [PATCH v2 4/4] Extra tests Nikolay Shaplov <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox